<?php

namespace App\Http\Controllers;

use Encore\Admin\Controllers\HasResourceActions;
use App\Models\PayLog;
use App\Models\Client;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Request;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Yansongda\Pay\Pay;
use GuzzleHttp\Client as GuzzleClient;

class AlipayController extends Controller
{

    public function payment()
    {
        $config = config('alipay.pay');
        return Pay::alipay($config);
    }

    public function notify(\Illuminate\Http\Request $request)
    {
        try {
            $alipay = $this->payment();
            //验证签名
            if (!$alipay->verify()) return 'success';
            $payLog = PayLog::where('out_trade_no', $request->out_trade_no)->first();
            if (!$payLog || $payLog->paid_at) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉支付宝，我已经处理完了，订单没找到，别再通知我了
            }
            if ($request->trade_status === 'TRADE_SUCCESS' || $request->trade_status === 'TRADE_FINISHED') {
                // 更新 PayLog, 这里的字段都是根据微信支付结果通知的字段设置的(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8)
                PayLog::where('out_trade_no', $request->out_trade_no)->update([
                    'total_fee' => $request->buyer_pay_amount,
                    'trade_type' => '支付宝扫码',
                    'paid_at' => time(),
                    'cash_fee' => $request->receipt_amount,
                    'transaction_id' => $request->trade_no,
                    'status' => 1,//充值成功
                    'result_code' => $request->trade_status,
                ]);
                //用户帐户余额增加
                Db::update('update clients set cash=cash + ' . $request->buyer_pay_amount . ' where id = ?', [$payLog->client_id]);
                file_put_contents('../storage/logs/update_cash.txt', '|用户client_id:'.$payLog->client_id.'-type:支付宝-时间：'.date('Y-m-d H:i:s').'-金额：'.$request->buyer_pay_amount, FILE_APPEND);
                //发送数据给客户的服务器进行保存,改变状态
                $pay_data = [
                    'form_params' => [        //参数组
                        'out_trade_no' => $request->out_trade_no,
                        'status' => 1,//充值成功
                        'total_fee' => $request->buyer_pay_amount,
                        'trade_type' => '支付宝扫码',
                        'paid_at' => time(),
                        'transaction_id' => $request->trade_no,
                        'result_code' => $request->trade_status,
                    ],
                ];

                try {
                    $send_url = "http://{$payLog->client_url}/api/alipay/state";
                    $this->guzzle($send_url, $pay_data);
                } catch (RequestException $e) {
                    file_put_contents('../storage/logs/pay_log.txt', '|' . $send_url . ':' . $e->getRequest(), FILE_APPEND);
                }
            } else {
                // 如果支付失败, 也更新 PayLog, 跟上面一样, 就是多了 error 信息
                PayLog::where('out_trade_no', $request->out_trade_no)->update([
                    'total_fee' => $request->buyer_pay_amount,
                    'trade_type' => '支付宝扫码',
                    'paid_at' => time(),
                    'cash_fee' => $request->receipt_amount,
                    'transaction_id' => $request->trade_no,
                    'status' => 2,
                    'result_code' => $request->trade_status,
                ]);
                //发送数据给客户的服务器进行保存,改变状态
                $pay_data = [
                    'form_params' => [        //参数组
                        'out_trade_no' => $request->out_trade_no,
                        'status' => 2,
                        'total_fee' => $request->buyer_pay_amount,
                        'trade_type' => '支付宝扫码',
                        'paid_at' => time(),
                        'transaction_id' => $request->trade_no,
                        'result_code' => $request->trade_status,
                    ],
                ];
                try {
                    $send_url = "http://{$payLog->client_url}/api/alipay/state";
                    $this->guzzle($send_url, $pay_data);
                } catch (RequestException $e) {
                    file_put_contents('../storage/logs/pay_log.txt', '|' . $send_url . ':' . $e->getRequest(), FILE_APPEND);
                }
            }
            $alipay->success();
        } catch (\Exception $e) {
            file_put_contents('./alipay_log.txt', $e->getMessage());
            return 'success';
        }
    }

    public function place_order()
    {
        $request = Request::all();
        $client_url = $request['client_url_'];
        $post_price = $request['post_price'];
        $pay_price = env('APP_DEBUG') ? 0.01 : $post_price;
        $pay_log = PayLog::where('client_url', $client_url)->where('status', 0)->where('pay_type', 42)->first();
        if (count($pay_log)) {
            $order_sn = $pay_log->out_trade_no;
            $pay_log->post_price = $post_price;//更新提交的价格
            $pay_log->save();
        } else {
            $order_sn = date('ymd') . substr(time(), -5) . substr(microtime(), 2, 5);//订单号
            $client_id = Client::where('client_url', $client_url)->value('id');
            if (!$client_id) return ['code' => 202, 'msg' => '用户不存在'];
            // 创建 Paylog 记录
            Db::table('pay_logs')->insert([
                'appid' => config('alipay.pay.app_id'),
                'out_trade_no' => $order_sn,
                'post_price' => $post_price,
                'pay_type' => 42,//支付宝
                'order_at' => time(),
                'client_id' => $client_id,
                'client_url' => $client_url,
            ]);
        }
        $pay_data = [
            'form_params' => [        //参数组
                'out_trade_no' => $order_sn,
                'post_price' => $post_price,
                'pay_type' => 42,//支付宝
                'order_at' => time(),
            ],
        ];
        //写入客户的数据库
        try {
            $send_url = "http://{$client_url}/api/alipay/paylog";
            $this->guzzle($send_url, $pay_data);
        } catch (\Exception $e) {
            file_put_contents('../storage/logs/pay_log.txt', '|' . $client_url . ':' . $e->getMessage().date('Ymd H:i:s'), FILE_APPEND);
            return;
        }
        //生成码
        $aliPayOrder = [
            'out_trade_no' => $order_sn,
            'total_amount' => $pay_price, // 支付金额
            'subject' => '支付宝-扫码充值' // 备注
        ];
        $scan = $this->payment()->scan($aliPayOrder);
        if (empty($scan->code) || $scan->code !== '10000') return false;

        return json_encode([
            'code' => 200,
            'title' => '支付宝充值',
            'money' => $pay_price . '元',
            // 订单编号, 用于在当前页面向微信服务器发起订单状态查询请求
            'order_sn' => $order_sn,
            // 生成二维码
            'html' => QrCode::encoding('UTF-8')->size(200)->generate($scan->qr_code),
        ]);
    }

    public function return_url()
    {
        echo 'success';
    }

    public function guzzle($url, $params)
    {
        $client = new GuzzleClient([
            // 超时
            'timeout' => 5.0,
        ]);
        return $client->request('POST', $url, $params);
    }

    //获取余额
    public function get_cash(){
        $cash = Client::where('sign', Request::get('sign'))->value('cash');
//        return json_encode(['cash' => $cash]);
        return ['cash' => $cash];
    }
    //获得订单的状态
    public function paid( )
    {
        $out_trade_no = Request::get('out_trade_no');
        $collection = $this->payment()->find($out_trade_no);
        if ($collection->code === '10000' && $collection->trade_status == 'TRADE_SUCCESS'){
            return json_encode([
                'code' => 200,
                'msg' => 'paid'
            ]);
        }else{
            return json_encode([
                'code' => 202,
                'msg' => 'not paid'
            ]);
        }
    }

}
